package com.kun.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kun.constant.SecurityConstant;
import com.kun.dto.SysTenantBo;
import com.kun.dto.UserDto;
import com.kun.entity.*;
import com.kun.mapper.SysRoleMenuMapper;
import com.kun.mapper.SysTenantMapper;
import com.kun.mapper.SysTenantPackageMapper;
import com.kun.service.SysDeptService;
import com.kun.service.SysRoleService;
import com.kun.service.SysTenantService;
import com.kun.service.SysUserService;
import com.kun.util.StringUtils;
import com.kun.vo.SysRolePermission;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * 租户
 *
 * @author kun.li
 */
@Service
@RequiredArgsConstructor
public class SysTenantServiceImpl extends ServiceImpl<SysTenantMapper, SysTenant> implements SysTenantService {


    private final SysUserService sysUserService;

    private final SysDeptService sysDeptService;

    private final SysRoleService sysRoleService;

    private final SysRoleMenuMapper sysRoleMenuMapper;


    private final SysTenantMapper sysTenantMapper;

    private final SysTenantPackageMapper sysTenantPackageMapper;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean saveTenant(SysTenantBo sysTenantBo) {
        String tenantId = IdUtil.simpleUUID();
        sysTenantBo.setTenantId(tenantId);
        SysTenant sysTenant = new SysTenant();
        BeanUtil.copyProperties(sysTenantBo, sysTenant);
        boolean flag = baseMapper.insert(sysTenant) > 0;
        if (!flag) {
            throw new RuntimeException("创建租户失败");
        }
        initUser(sysTenantBo);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateTenant(SysTenantBo bo) {
        SysTenant sysTenant = new SysTenant();
        BeanUtil.copyProperties(bo, sysTenant);
        boolean flag = sysTenantMapper.updateById(sysTenant) > 0;
        if (!flag) {
            throw new RuntimeException("租户修改失败");
        }
        return true;
    }

    @Override
    public Boolean syncTenantPackage(String tenantId, String packageId) {
        // 修改租户
        SysTenantPackage sysTenantPackage = sysTenantPackageMapper.selectById(packageId);
        List<String> menuIds = StringUtils.splitTo(sysTenantPackage.getMenuIds(), Convert::toStr);
        List<SysRole> roleList = sysRoleService.list(Wrappers.<SysRole>lambdaQuery().eq(SysRole::getTenantId, tenantId));
        List<String> roleIds = new ArrayList<>(roleList.size() - 1);
        roleList.forEach(item -> {
            if (SecurityConstant.TENANT_ADMIN_ROLE_CODE.equals(item.getRoleCode())) {
                // 删除角色和菜单的关联表
                // 重新新增角色和菜单的关联表
                SysRolePermission sysRolePermission = new SysRolePermission();
                sysRolePermission.setRoleId(item.getRoleId());
                sysRolePermission.setMenuIds(menuIds);
                sysRoleService.assignmentPermission(sysRolePermission);
            } else {
                roleIds.add(item.getRoleId());
            }
        });
        if (!roleIds.isEmpty()) {
            sysRoleMenuMapper.delete(
                    new LambdaQueryWrapper<SysRoleMenu>().in(SysRoleMenu::getRoleId, roleIds).notIn(!menuIds.isEmpty(), SysRoleMenu::getMenuId, menuIds));
        }
        return true;
    }

    @Override
    public Boolean removeTenant(String id) {
        return sysTenantMapper.deleteById(id) > 0;
    }

    private boolean compareMenu(String oleMenuIds, String newMenuIds) {
        String oleMenuMd5Value = DigestUtils.md5DigestAsHex(oleMenuIds.getBytes());
        String newMenuMd5Value = DigestUtils.md5DigestAsHex(newMenuIds.getBytes());
        return oleMenuMd5Value.equals(newMenuMd5Value);
    }

    public void initUser(SysTenantBo sysTenantBo) {
        String tenantId = sysTenantBo.getTenantId();
        // 获取租户套餐
        SysTenantPackage tenantPackage = sysTenantPackageMapper.selectById(sysTenantBo.getPackageId());
        if (ObjectUtil.isNull(tenantPackage)) {
            throw new RuntimeException("套餐不存在");
        }
        // 获取套餐菜单id
        List<String> menuIds = StringUtils.splitTo(tenantPackage.getMenuIds(), Convert::toStr);

        /*
          创建部门 创建角色 创建用户 给角色分配菜单
         */
        // 创建部门
        SysDept sysDept = new SysDept();
        sysDept.setTenantId(tenantId);
        sysDept.setDeptName(sysTenantBo.getCompanyName());
        sysDept.setParentId("-1");
        sysDept.setWeight(0L);
        sysDeptService.save(sysDept);
        // 创建角色
        SysRole sysRole = new SysRole();
        sysRole.setRoleCode(SecurityConstant.TENANT_ADMIN_ROLE_CODE);
        sysRole.setTenantId(tenantId);
        sysRole.setRoleName(SecurityConstant.TENANT_ADMIN_ROLE_NAME);
        sysRole.setDsType(0);
        sysRole.setHasAdmin(0);
        sysRoleService.save(sysRole);
        // 创建角色菜单

        SysRolePermission sysRolePermission = new SysRolePermission();
        sysRolePermission.setRoleId(sysRole.getRoleId());
        sysRolePermission.setMenuIds(menuIds);
        sysRoleService.assignmentPermission(sysRolePermission);
        // 创建系统用户 以及 角色和用户关联
        UserDto userDto = new UserDto();
        userDto.setTenantId(tenantId);
        userDto.setUsername(sysTenantBo.getUsername());
        userDto.setPassword(sysTenantBo.getPassword());
        userDto.setDeptId(sysDept.getDeptId());
        userDto.setState(0);
        userDto.setRole(Collections.singletonList(sysRole.getRoleId()));
        sysUserService.saveUser(userDto);
    }
}
